#include "stdafx.h"
#include "FndErrReportTestSuite.h"
#include "RandString.h"

using namespace CO::SpiFoundation::ErrorHandling;
using namespace std;

FndErrReportTestSuite::FndErrReportTestSuite( int v ) : verbose(v)
{
	TEST_ADD(FndErrReportTestSuite::reportTest1);
	TEST_ADD(FndErrReportTestSuite::reportTest2);
}

//
// reportTest1
//    test for self-consistency : what() == toString() for all defined errors
//
void FndErrReportTestSuite::reportTest1()
{
	ostringstream out;

	for( list<BaseErrorType*>::iterator i=l.errors.begin(); i!=l.errors.end(); i++ )
	{
		BaseErrorType* error      = *i;
		const char*    error_name = error->getName();

		if( 0 != strncmp( error->what(), error->toString().c_str(), error->toString().length()) )
		{
			out << "Error strings inconsistent for " << error_name << ":\n\t" 
				<< error->what() << "\n\t\t!=\n\t" 
				<< error->toString() << "\n\n";
		}
	}

	if( 0 != out.str().length() )
	{
		TEST_FAIL( "error output strings inconsistent" );
		if( verbose ) cout << out.str();
	}
}

//
// reportTest2
//     test BaseError contructor parameters
//
void FndErrReportTestSuite::reportTest2()
{
	ostringstream out;

	typedef map<const char*,BaseErrorType*> errorNameArray;
	errorNameArray prev;

	list<BaseErrorType*> errors;

	for( int activeobj = 0; activeobj < 4; activeobj++ )
	for( int errid = 0; errid < 4; errid++ )
	for( int sev=ESEVunknown; sev <= ESEVfatal; sev++ )
	{
		errors.clear();
		//
		// ------------------------------------------------------------------------------
		//
		// add new errors here
		//
		errors.push_back( new BaseError( errid, sev ) );
		//
		// ------------------------------------------------------------------------------
		//

		for( list<BaseErrorType*>::iterator i=errors.begin(); i!=errors.end(); i++ )
		{
			BaseErrorType* err        = *i;
			const char*    error_name = err->getName();

			if( 0 != strncmp( err->what(), err->toString().c_str(), err->toString().length()) )
			{
				out << "Parameterized error strings inconsistent for " << error_name << ":\n\t" 
					<< err->what() << "\n\t\t!=\n\t" 
					<< err->toString() << "\n\n";
			}
			
			if( prev[error_name] )
			{
				if( err->toString() == prev[error_name]->toString() )
				{
					out << "Base error parameters do not alter string for " << error_name << ":\n\t"
						<< err->toString() << "\n\t\t==\n\t" 
						<< prev[error_name]->toString() << "\n\n";
				}
				delete prev[error_name];
			}
			prev[error_name] = err;
		}
	}
	for( errorNameArray::iterator i=prev.begin(); i!=prev.end(); i++ )	delete i->second;
	if( 0 != out.str().length() )
	{
		TEST_FAIL( "Parameterized error output strings FAIL" );
		if( verbose ) cout << out.str();
	}
}
